#include "CVideoManager.h"
#include "CCore.h"

std::auto_ptr<CVideoManager> CVideoManager::m_instance;

CVideoManager::CVideoManager()
{
    bFullScreen = false;
    Screen.p_Surface = NULL;
    Screen.pr_VideoManager = this;
}

CVideoManager::~CVideoManager()
{
    Release();
}

bool CVideoManager::Release()
{
    for (int i = (int)Images.size()-1; i >= 0; i--){
        if (Images[i]){
            delete Images[i];
            Images.erase(Images.begin()+i);
            break;
        }
    }

    Images.clear();
    SDL_QuitSubSystem(SDL_INIT_VIDEO);
    return true;
}

bool CVideoManager::Initialize()
{
    int iResult = SDL_InitSubSystem(SDL_INIT_VIDEO);
    if (iResult < 0)
        return false;
    Screen.Release();
    return true;
}

CImage * CVideoManager::LoadImage(const std::string&  cp_chFileName)
{
    for (int i = (int)Images.size()-1; i>=0; i--){
        if (!Images[i]->FileName.compare(cp_chFileName)){
            Images[i]->sReferences++;
            return Images[i];
        }
    }

    CImage *p_Image = new CImage();
    if (p_Image){
        p_Image->pr_VideoManager = this;
        p_Image->LoadFromFile(cp_chFileName);

        Images.push_back(p_Image);
        return p_Image;
    }

    CException("[CVideoManager::LoadImage@87] Error: Return can't be NULL.").Raise();
    return NULL;
}

bool CVideoManager::DeleteImage(CImage **p_Image)
{
    if (p_Image && *p_Image){
        for (int i = (int)Images.size()-1; i >= 0; i--){
            if (Images[i] == *p_Image){
                if (Images[i]->sReferences > 0)
                    Images[i]->sReferences--;
                else{
                    (*p_Image)->Release();
                    delete *p_Image;
                    Images.erase(Images.begin()+i);
                }
                *p_Image = NULL;
                return true;
            }
        }
    }
    return false;
}

void CVideoManager::Blit()
{
#ifdef _SOFT
    SDL_Flip(Screen.p_Surface);
#endif

#ifdef _HARD
    SDL_UpdateRect(Screen.p_Surface,0,0,0,0);
#endif
}

void CVideoManager::SetVideoMode(bool bFullscreenPam, int h,int w)
{
    SetVideoMode(bFullscreenPam,CVector(h,w));
}

void CVideoManager::SetVideoMode(bool bFullscreenPam, const CVector& NewSize)
{
    WindowSize = NewSize;
    if (bFullscreenPam == true){
        Screen.p_Surface = SDL_SetVideoMode( (int)NewSize.fx, (int)NewSize.fy, 16, SDL_FULLSCREEN | _FLAGS);
        bFullScreen = true;
    }else{
        Screen.p_Surface = SDL_SetVideoMode( (int)NewSize.fx, (int)NewSize.fy, 16, _FLAGS);
        bFullScreen = false;
    }

    if (Screen.p_Surface == NULL)
        Release();
}

void CVideoManager::SetAppName(const std::string&  namePam,const std::string&   iconFilePam)
{
    SDL_WM_SetCaption(namePam.c_str(),iconFilePam.c_str());
    SDL_WM_SetIcon(SDL_LoadBMP(iconFilePam.c_str()), NULL);
}

void CVideoManager::ClearScreen()
{
    SDL_Rect rect;
    rect.h = Screen.p_Surface->h;
    rect.w = Screen.p_Surface->w;
    rect.x = 0;
    rect.y = 0;
    SDL_FillRect(Screen.p_Surface, &rect, 0);
}
